package com.konke.sdslibrary.factroy;

import android.content.Context;

import com.konke.sdslibrary.DataSourceFactory;
import com.konke.sdslibrary.HostContext;
import com.konke.sdslibrary.HostContextManager;
import com.konke.sdslibrary.SmartHomeApi;
import com.konke.sdslibrary.SmartHomeCallback;
import com.konke.sdslibrary.SmartHomeFactoryApi;
import com.konke.sdslibrary.event.DeviceUnBindEvent;
import com.konke.sdslibrary.model.SmartHomeStatus;
import com.sds.sdk.android.sh.common.SHClientState;
import com.sds.sdk.android.sh.common.SHErrorCode;
import com.sds.sdk.android.sh.model.AlarmNotifyEvent;
import com.sds.sdk.android.sh.model.ArmingStateChangedEvent;
import com.sds.sdk.android.sh.model.BoolSensorActivedEvent;
import com.sds.sdk.android.sh.model.CodeLibUploadResultPushEvent;
import com.sds.sdk.android.sh.model.CodedLockAlarmPushEvent;
import com.sds.sdk.android.sh.model.CodedLockReadCardPushEvent;
import com.sds.sdk.android.sh.model.ControllerSmartSwitchPushEvent;
import com.sds.sdk.android.sh.model.CreateNewCodeLibPushEvent;
import com.sds.sdk.android.sh.model.DetectDevPowerResultPushEvent;
import com.sds.sdk.android.sh.model.DeviceAppArgsChangedPushEvent;
import com.sds.sdk.android.sh.model.DeviceStatusChangedPushEvent;
import com.sds.sdk.android.sh.model.DooyaOptEvent;
import com.sds.sdk.android.sh.model.FancoilConfigArgEvent;
import com.sds.sdk.android.sh.model.FloorheatingConfigArgEvent;
import com.sds.sdk.android.sh.model.FloorheatingDevTempEvent;
import com.sds.sdk.android.sh.model.FreshAirConfigArgEvent;
import com.sds.sdk.android.sh.model.GetZigbeeDevsHwInfoPushEvent;
import com.sds.sdk.android.sh.model.GwUpgradeResultPushEvent;
import com.sds.sdk.android.sh.model.IdentifyPushEvent;
import com.sds.sdk.android.sh.model.InfraredPushEvent;
import com.sds.sdk.android.sh.model.KitInstallStatusPushEvent;
import com.sds.sdk.android.sh.model.LockRemoteOpenDisableEvent;
import com.sds.sdk.android.sh.model.LockSwitchPushEvent;
import com.sds.sdk.android.sh.model.MatchCloudCodelibResultPushEvent;
import com.sds.sdk.android.sh.model.MatchCodeLibPushEvent;
import com.sds.sdk.android.sh.model.NewDeviceNotifyEvent;
import com.sds.sdk.android.sh.model.NewDevicePushEvent;
import com.sds.sdk.android.sh.model.OpenLockUserPushEvent;
import com.sds.sdk.android.sh.model.PushEvent;
import com.sds.sdk.android.sh.model.RFLearnPushEvent;
import com.sds.sdk.android.sh.model.RoomStateChangedEvent;
import com.sds.sdk.android.sh.model.ShortcutPanelActivedEvent;
import com.sds.sdk.android.sh.model.SmartSwitchPushEvent;
import com.sds.sdk.android.sh.model.SycnPushEvent;
import com.sds.sdk.android.sh.model.YaleLockIndoorForceLockEvent;
import com.sds.sdk.android.sh.model.ZigbeeDeviceJoinEvent;
import com.sds.sdk.android.sh.model.ZigbeeNodeReplacePushEvent;
import com.zsj.comminlibrary.util.log.XLog;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 中控主机连接管理
 */
public class CcuHostManager implements HostContextManager, SmartHomeCallback {

    private static Map<String, HostContext> smartHomeMap = new HashMap<>();//key:ccuname,value:HostContext
    private Map<String, String> smartName2DevId;//ccu name->ccu id
    private SmartHomeFactoryApi smartHomeFactoryApi;
    private Context context;
    private Map<String, SHClientState> mStateMap;

    public CcuHostManager(Context context) {
        this.context = context;
        smartName2DevId = new HashMap<>();
        smartHomeFactoryApi = DataSourceFactory.getSmartHomeFactory(this);
        mStateMap = new HashMap<>();
        EventBus.getDefault().register(this);
    }

    public void connectCCU(String userName,String ccuName, String ccuId, String acccessKey) {
        XLog.f("connect ccu with ccuName:"+ccuName+",ccuId:"+ccuId);
        disconnectCCU();
//        if (smartHomeMap.containsKey(ccuId)) {
//            HostContext context = smartHomeMap.get(ccuId);
//            if (context != null && !(context instanceof NullHostManager)) {
//                if (mStateMap != null && mStateMap.keySet().contains(ccuName) && mStateMap.get(ccuName).equals(SHClientState.LINK_BROKN)) {
//                    context.reconect(0);
//                }
//            }
//            return;
//        } else {
            SmartHomeApi smartHomeApi = smartHomeFactoryApi.createSmartHome(context, userName,ccuName, acccessKey);
            HostContext hostContext = new HostManager(smartHomeApi);
            smartHomeMap.put(ccuId, hostContext);
            XLog.f("add new client with ccuName:"+ccuName+",ccuId:"+ccuId);
            smartName2DevId.put(ccuName, ccuId);
            mStateMap.put(ccuName, SHClientState.INIT);
//        }
    }

    @Override
    public void disconnectCCU(String ccuId) {
        if (smartHomeMap == null)
            return;
        HostContext hostContext = smartHomeMap.get(ccuId);

        if (hostContext != null) {
            hostContext.destroy();
            smartHomeMap.remove(ccuId);
            XLog.f("discon ccu client with ccuId:"+ccuId);
        }
        if (mStateMap != null&&mStateMap.containsKey(getCcuIdByName(ccuId))) {
            mStateMap.remove(getCcuIdByName(ccuId));
        }
    }
    @Override
    public void disconnectCCU() {
        if (smartHomeMap == null)
            return;
        for (String s : smartHomeMap.keySet()) {
            HostContext  hostContext = smartHomeMap.get(s);
            hostContext.destroy();
            smartHomeMap.remove(s);
        }
    }


    @Override
    public HostContext getContext(String ccuId) {
        XLog.e("get context  "+smartHomeMap.isEmpty());
        HostContext hostContext = smartHomeMap.get(ccuId);
        XLog.f("get ccu client with ccuId:"+ccuId+",return:"+hostContext);
        if (hostContext == null) {
            return new NullHostManager();
        }
        return hostContext;
    }

    @Override
    public HostContext getContext() {
        XLog.e("get context  "+smartHomeMap.isEmpty());
        if (smartHomeMap == null || smartHomeMap.isEmpty()) {
            return new NullHostManager();
        }
        HostContext hostContext = null;
        for (String s : smartHomeMap.keySet()) {
            hostContext = smartHomeMap.get(s);
            break;
        }
        if (hostContext == null) {
            return new NullHostManager();
        }
        return hostContext;
    }

    @Override
    public String getCcuIdByName(String ccuName) {
        return smartName2DevId.get(ccuName);
    }

    @Override
    public String getCcuNameById(String id) {
        if (smartName2DevId == null) {
            return null;
        }
        Set<String> kset = smartName2DevId.keySet();
        if (kset == null) {//#17203 java.lang.NullPointerException
            return null;
        }
        for (String ks : kset) {
            if (id.equals(smartName2DevId.get(ks))) {
                return ks;
            }
        }
        return null;
    }

    @Override
    public void stopCCU(String ccuName) {
        smartHomeFactoryApi.StopSmartHome(ccuName);
    }

    @Override
    public void onSmartHomeStateChanged(String ccuName, SHClientState currentState, SHErrorCode errorCode, boolean isLanCon) {
        XLog.f("ccu:"+ccuName+",state:"+currentState);
        SmartHomeStatus statusEvent = new SmartHomeStatus(smartName2DevId.get(ccuName));
        statusEvent.setStatus(currentState);
        statusEvent.setLanConn(isLanCon);
        statusEvent.setErrorCode(errorCode);
        EventBus.getDefault().post(statusEvent);
        mStateMap.put(ccuName, currentState);
    }

    @Override
    public void onSmartHomeEventReceived(String ccuName, PushEvent event) {
        XLog.i("ccu:" + ccuName + ",push:" + event);
        if (event instanceof DeviceStatusChangedPushEvent) {
            HostEventDispatcher.dispatchDeviceStatusChangedPushEvent((DeviceStatusChangedPushEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof ArmingStateChangedEvent) {
            HostEventDispatcher.dispatchArmingStatusChangedPushEvent((ArmingStateChangedEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof LockRemoteOpenDisableEvent) {
            HostEventDispatcher.dispatchKonkeLockRemoteOpenDisablePushEvent((LockRemoteOpenDisableEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof YaleLockIndoorForceLockEvent) {
            HostEventDispatcher.dispatchYaleLockIndoorForeceLockPushEvent((YaleLockIndoorForceLockEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof DooyaOptEvent) {
            HostEventDispatcher.dispatchDooyaOptPushEvent((DooyaOptEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof LockSwitchPushEvent) {
            HostEventDispatcher.dispatchLockSwitchPushEvent((LockSwitchPushEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof OpenLockUserPushEvent) {
            OpenLockUserPushEvent e = (OpenLockUserPushEvent) event;
            XLog.f("usrid"+e.getUserId()+"  deviceId"+e.getId());
            HostEventDispatcher.dispatchOpenLockUserPushEvent((OpenLockUserPushEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof ShortcutPanelActivedEvent) {
            HostEventDispatcher.dispatchShortcutPanelActivedEvent((ShortcutPanelActivedEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof AlarmNotifyEvent) {
            HostEventDispatcher.dispatchAlarmNotifyEvent((AlarmNotifyEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof BoolSensorActivedEvent) {
            HostEventDispatcher.dispatchBoolSensorActivedEvent((BoolSensorActivedEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof IdentifyPushEvent) {
            HostEventDispatcher.dispatchIdentifyPushEvent((IdentifyPushEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof CodeLibUploadResultPushEvent) {
            HostEventDispatcher.dispatchCodeLibUploadResultPushEvent((CodeLibUploadResultPushEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof MatchCloudCodelibResultPushEvent) {
            HostEventDispatcher.dispatchMatchCloudCodelibResultPushEvent((MatchCloudCodelibResultPushEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof CreateNewCodeLibPushEvent) {
            HostEventDispatcher.dispatchCreateNewCodeLibPushEvent((CreateNewCodeLibPushEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof ControllerSmartSwitchPushEvent) {
            HostEventDispatcher.dispatchControllerSmartSwitchPushEvent((ControllerSmartSwitchPushEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof DetectDevPowerResultPushEvent) {
            HostEventDispatcher.dispatchDetectDevPowerResultPushEvent((DetectDevPowerResultPushEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof SmartSwitchPushEvent) {
            HostEventDispatcher.dispatchSmartSwitchPushEvent((SmartSwitchPushEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof NewDevicePushEvent || event instanceof NewDeviceNotifyEvent) {
            XLog.e(""+event);
            HostEventDispatcher.dispatchNewDevicePushEvent(smartName2DevId.get(ccuName));
        } else if (event instanceof InfraredPushEvent) {
            HostEventDispatcher.dispatchInfraredPushEvent((InfraredPushEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof RFLearnPushEvent) {
            HostEventDispatcher.dispatchRFPushEvent((RFLearnPushEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof GwUpgradeResultPushEvent) {
            HostEventDispatcher.dispatchGwUpgradResultEvent((GwUpgradeResultPushEvent) event, smartName2DevId.get(ccuName));
        }else if (event instanceof RoomStateChangedEvent) {
            HostEventDispatcher.dispatchRoomStateChangedEvent((RoomStateChangedEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof DeviceAppArgsChangedPushEvent) {
            HostEventDispatcher.dispatchDeviceAppArgsChangedPushEvent((DeviceAppArgsChangedPushEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof KitInstallStatusPushEvent) {
            HostEventDispatcher.dispatchKitInstallStatusPushEvent((KitInstallStatusPushEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof ZigbeeDeviceJoinEvent) {
            HostEventDispatcher.dispatchZigbeeDeviceJoinEvent((ZigbeeDeviceJoinEvent)event,smartName2DevId.get(ccuName));
        } else if (event instanceof CodedLockReadCardPushEvent) {
            HostEventDispatcher.dispatchCodedLockReadCardPushEvent((CodedLockReadCardPushEvent)event, smartName2DevId.get(ccuName));
        }else if (event instanceof SycnPushEvent) {
            HostEventDispatcher.dispatchSycnPushEvent(smartName2DevId.get(ccuName));
        }  else if (event instanceof CodedLockAlarmPushEvent) {
            HostEventDispatcher.dispatchCodedLockAlarmPushEvent((CodedLockAlarmPushEvent)event, smartName2DevId.get(ccuName));
        } else if (event instanceof ZigbeeNodeReplacePushEvent) {
            HostEventDispatcher.dispatchZigbeeRepalceEvent((ZigbeeNodeReplacePushEvent)event, smartName2DevId.get(ccuName));
        } else if (event instanceof GetZigbeeDevsHwInfoPushEvent) {
            HostEventDispatcher.dispatchGetZigbeeDevsHwInfoPushEvent((GetZigbeeDevsHwInfoPushEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof MatchCodeLibPushEvent) {
            HostEventDispatcher.dispatchMatchCloudCodelibPushEvent((MatchCodeLibPushEvent)event, smartName2DevId.get(ccuName));
        } else if (event instanceof FloorheatingDevTempEvent) {
            HostEventDispatcher.dispatchFloorheatingDevTempEvent((FloorheatingDevTempEvent)event, smartName2DevId.get(ccuName));
        } else if (event instanceof FancoilConfigArgEvent) {
            HostEventDispatcher.dispatchFancoilConfigArg((FancoilConfigArgEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof FloorheatingConfigArgEvent) {
            HostEventDispatcher.dispatchFloorheatingConfigArg((FloorheatingConfigArgEvent) event, smartName2DevId.get(ccuName));
        } else if (event instanceof FreshAirConfigArgEvent) {
            HostEventDispatcher.dispatchFreshAirConfigArg((FreshAirConfigArgEvent) event, smartName2DevId.get(ccuName));
        }
    }

    @Subscribe
    public void onDeviceUnBindEvent(DeviceUnBindEvent event) {
        disconnectCCU();
    }
}
